/*
 * @(#)LotusDominoReceiverImpl.java
 *
 * Copyright (c) 2005 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.mail.core;

import java.io.File;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.mail.Message;
import javax.servlet.http.HttpServletRequest;

import lotus.domino.Database;
import lotus.domino.DateTime;
import lotus.domino.Document;
import lotus.domino.DocumentCollection;
import lotus.domino.EmbeddedObject;
import lotus.domino.NotesFactory;
import lotus.domino.RichTextItem;
import lotus.domino.Session;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.mail.bean.EmailAttachment;
import com.dcivision.mail.bean.EmailAttachmentImpl;
import com.dcivision.mail.bean.EmailFolder;
import com.dcivision.mail.bean.EmailMessage;
import com.dcivision.mail.bean.EmailMessageImpl;
import com.dcivision.mail.bean.LotusDominoFolderImpl;
import com.dcivision.mail.bean.MailSetting;
import com.dcivision.mail.dao.MailSettingDAObject;

/**
 * LotusDominoReceiverImpl.java
 *
 * This class about receive email.
 *
 * @author Rollo Chan
 * @company DCIVision Limited
 * @creation date 14/01/2005
 * @version $Revision: 1.16.2.2 $
 */

public class LotusDominoReceiverImpl extends EmailReceiver implements java.io.Serializable {

  public static final String REVISION = "$Revision: 1.16.2.2 $";

  public final static int PRIORITY_HIGHEST = 5;

  public final static int PRIORITY_HIGH = 4;

  public final static int PRIORITY_NORMAL = 3;

  public final static int PRIORITY_LOW = 2;

  public final static int PRIORITY_LOWEST = 1;

  private MailSetting mailSetting = null;

  private EmailFolder folder = null;

  private SessionContainer sessionContainer = null;

  private List mailList = new ArrayList();

  public static String SORT_ASC = "ASC";

  public static String SORT_DSC = "DSC";

  private String isDelete = "";

  private boolean deleteTheEmail = false;

  protected Log log = LogFactory.getLog(this.getClass().getName());

  private LotusDominoReceiverImpl(SessionContainer sessionContainer) {
    this.sessionContainer = sessionContainer;
  }

  public static LotusDominoReceiverImpl newInstance(SessionContainer sessionContainer) {
    return new LotusDominoReceiverImpl(sessionContainer);
  }

  private void getMailSetting() throws ApplicationException {
    if (this.mailSetting == null) {
      Connection conn = null;
      try {
        conn = com.dcivision.framework.DataSourceFactory.getConnection();
        MailSettingDAObject mailSettingDAO = new MailSettingDAObject(sessionContainer, conn);
        this.mailSetting = (MailSetting) mailSettingDAO.getObjectByUserRecordID(sessionContainer.getUserRecordID());
        this.isDelete = this.mailSetting.getParameter3();
        if (isDelete == null || isDelete == "") {
          deleteTheEmail = true;
        }
      } catch (Exception e) {
        log.error(e, e);
        throw new ApplicationException(com.dcivision.framework.ErrorConstant.COMMON_FATAL_ERROR, e);
      } finally {
        try {
          conn.close();
        } catch (Exception ignore) {
        } finally {
          conn = null;
        }
      }
    }
  }

  /**
   * Method loadMailList()
   *
   * @param host
   * @param name
   * @param password
   * @param protocol
   * @return mail list
   * @throws Exception
   */
  public List loadMailList(String host, String name, String password, String protocol) throws Exception {
    getMailSetting();
    Session session = null;
    Database databaseObject = null;
    DocumentCollection docCol = null;
    String dbFilePath = "mail\\" + name + ".nsf";
    try {
      String ior = NotesFactory.getIOR(host);
      log.debug("host:" + host);
      log.debug("name:" + name);
      log.debug("password:" + password);
      log.debug("IOR:" + ior);

      session = NotesFactory.createSessionWithIOR(ior, name, password);

      String serverName = session.getServerName();
      log.debug("serverName is " + serverName);
      log.debug("dbFilePath is " + dbFilePath);

      databaseObject = session.getDatabase(session.getServerName(), dbFilePath);
      folder = new LotusDominoFolderImpl(databaseObject);
      folder.open(0);

      docCol = databaseObject.getAllDocuments();
      log.debug("Mail No.:" + docCol.getCount());

      int n = 0;
      Document doc = docCol.getFirstDocument();
      while (doc != null) {
        EmailMessageImpl emailMessage = EmailMessageImpl.newInstance();
        n++;

        emailMessage.setID(new Integer(Integer.parseInt(doc.getNoteID(), 16)));
        emailMessage.setMessageID(doc.getNoteID());
        emailMessage.setSubject(TextUtility.noNull(doc.getItemValueString("Subject")));
        emailMessage.setSender(Utility.isEmpty(doc.getItemValueString("DisplayFrom")) ? doc.getItemValueString("From")
            : doc.getItemValueString("DisplayFrom"));
        emailMessage.setSendDate(((DateTime) doc.getCreated()).toJavaDate());
        emailMessage.setTo(TextUtility.noNull(doc.getItemValueString("SendTo")));
        emailMessage.setCc(TextUtility.noNull(doc.getItemValueString("CopyTo")));
        emailMessage.setSize(doc.getSize());
        emailMessage.setIsTextOnly(!doc.hasEmbedded());

        int priority = PRIORITY_NORMAL;
        emailMessage.setPriority(priority);

        mailList.add(emailMessage);

        doc = docCol.getNextDocument();
      }
    } catch (Exception e) {
      log.error(e, e);
      throw e;
    } finally {
      folder.close(true);
      try {
        session.recycle();
      } catch (Exception ignore) {
      } finally {
        session = null;
      }
    }

    return mailList;
  }

  /**
   * Method getFolder
   *
   * @return
   */
  public EmailFolder getFolder() {
    return this.folder;
  }

  public EmailMessage getMessageContent(HttpServletRequest request, String mailId, String mailServerType)
      throws ApplicationException {
    getMailSetting();

    EmailMessage emailMessage = null;
    Session session = null;
    Database databaseObject = null;
    EmailFolder folder = null;
    String name=this.mailSetting.getIncomingServerLoginName();
    String password = com.dcivision.framework.Crypt.decrypt(this.mailSetting.getIncomingServerLoginPwd(), SystemParameterFactory
        .getSystemParameter(SystemParameterConstant.CRYPTO_SALT));
    //dbFilePath = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DOMINO_DB_FILE_PATH);
    String  dbFilePath = "mail\\" + name + ".nsf";
    try {
      List sessEmailList = (List) request.getSession(true).getAttribute("sessEmailList");
      emailMessage = EmailReceiver.getMailByID(sessEmailList, mailId);

      folder = (EmailFolder) request.getSession(true).getAttribute("folder");

      if (sessEmailList == null || emailMessage == null || folder == null) {
        // this.addError(request, "Cookie Expire,please login again.");
        return emailMessage;
      }

      // if the emailMessage is already get the content then not need get
      // the conent again
      if (emailMessage.getAnalyzed()) {
        return emailMessage;
      }
      // connect to lotus server
      String ior = NotesFactory.getIOR(this.mailSetting.getIncomingServerHost());
      log.debug("IOR:" + ior);
      session = NotesFactory.createSessionWithIOR(ior, name, password);

      //get mail data
      databaseObject = session.getDatabase(session.getServerName(), dbFilePath);
      folder = new LotusDominoFolderImpl(databaseObject);
      folder.open(0);

      Document doc = databaseObject.getDocumentByID(emailMessage.getMessageID());
      emailMessage.setContent(TextUtility.noNull(doc.getItemValueString("Body")));

      if (doc.hasEmbedded()) {
        RichTextItem body = (RichTextItem) doc.getFirstItem("Body");
        Vector vecAttch = body.getEmbeddedObjects();
        // log.debug("vecAttch.size():"+vecAttch.size());
        for (int i = 0; i < vecAttch.size(); i++) {
          EmbeddedObject emObj = (EmbeddedObject) vecAttch.get(i);
          saveAttach(emailMessage, putAttachToCatchFile(emObj, emailMessage.getID().intValue()));
        }
      }

      emailMessage.setEmailContentType(EmailMessage.EMAIL_CONTENT_TYPE_TXT);
      emailMessage.setAnalyzed(true);
    } catch (Exception e) {
      log.error(e, e);
      throw new ApplicationException(com.dcivision.framework.ErrorConstant.COMMON_FATAL_ERROR);
    } finally {
      try {
        folder.close(true);
      } catch (Exception ignore) {
      } finally {
        folder = null;
      }
      try {
        session.recycle();
      } catch (Exception ignore) {
      } finally {
        session = null;
      }
    }

    return emailMessage;
  }

  /**
   * Method EmailMessage
   *
   * use for mail archive to rule ,not use yet
   * @return
   */
  public EmailMessage getMessageContentNew(HttpServletRequest request, EmailMessage emailMessageInput,
      String mailServerType) throws ApplicationException {
    return getMessageContent(request,emailMessageInput.getMessageID(),mailServerType);
  }

  private EmailAttachment putAttachToCatchFile(EmbeddedObject bodyPart, int sequence) {
    EmailAttachment emailAttachment = new EmailAttachmentImpl();
    try {
      long currentTime = new java.util.Date().getTime();
      Double randomNum = new Double((Math.random() * 1000));
      String folderName = SystemParameterFactory
          .getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_CACHEFOLDER_PATH);
      File catcheFolder = new File(folderName);
      if (!catcheFolder.exists()) {
        catcheFolder.mkdir();
      }
      String fileName = sessionContainer.getUserRecordID() + "_" + currentTime + "_" + randomNum.intValue() + "_"
          + sequence + ".tmp";
      bodyPart.extractFile(folderName + fileName);

      emailAttachment.setAttachFileName(bodyPart.getName());
      emailAttachment.setCatchFileName((fileName));
      emailAttachment.setFileSize(bodyPart.getFileSize());
    } catch (Exception e) {
      log.error(e, e);
    }
    return emailAttachment;

  }

  private void saveAttach(EmailMessage emailMessage, EmailAttachment emailAttachment) throws Exception {
    emailMessage.addAttachment(emailAttachment);
  }

  /**
   * Method loadAndProcessMailList()
   *
   * @param host
   * @param name
   * @param password
   * @param protocol
   * @return mail list
   * @throws Exception
   */
  public List loadAndProcessMailList(String host, String name, String password, String protocol) throws Exception {
    return mailList;

  }

  /**
   * Method analyseMultipart() -- get the eamil attchment (MIME emails)
   *
   *
   *
   * @param emailMessage
   * @param mpart
   * @return EmailMessageImpl
   * @throws Exception
   */
  public EmailMessageImpl analysemailEmailMessage(Message msg) throws Exception {
    EmailMessageImpl emailMessage = EmailMessageImpl.newInstance();
    return emailMessage;
  }

  public void setEmailCharset(String charset) throws Exception {

  }

}
